using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;
using Serilog;
using Digitalmes.Core;
using Digitalmes.Infrastructure;

namespace Digitalmes.AvaloniaUI;

public partial class App : Application
{
    private Mutex? _mutex;

    private readonly IHost _host = Host.CreateDefaultBuilder()
        .UseCoreSetup()
        .UseInfrastructureSetup()
        .UseDesktopSetup()
        .UseSerilog((hostingContext, loggerConfiguration) =>
            loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration)
        ).Build();

    /// <summary>
    /// 获取当前的 Application 应用程序实例。
    /// </summary>
    public static new App? Current => Application.Current as App;

    /// <summary>
    /// Gets the <see cref="IServiceProvider"/> instance to resolve application services.
    /// </summary>
    public IServiceProvider Services => _host.Services;

    public override void Initialize()
    {
        AvaloniaXamlLoader.Load(this);
    }

    public override void OnFrameworkInitializationCompleted()
    {
        // 只允许开启一个应用（若是相同程序不同应用，需修改 name）
        _mutex = new(true, "Digitalmes.Desktop", out var createdNew);
        if (!createdNew)
        {
            Log.Information("应用程序已启动，不能同时开启多个。");
            Environment.Exit(0);
            return;
        }

        Log.Information("应用程序启动");

        _host.Start();

        // 使用 CommunityToolkit，则需要用下面一行移除 Avalonia 数据验证。
        // 如果没有这一行，数据验证将会在 Avalonia 和 CommunityToolkit 中重复。
        BindingPlugins.DataValidators.RemoveAt(0);

        if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
        {
            desktop.MainWindow = new MainWindow()
            {
                DataContext = new MainViewViewModel(),
            };
        }
        else if (ApplicationLifetime is ISingleViewApplicationLifetime singleView)
        {
            singleView.MainView = new SingleView()
            {
                DataContext = new MainViewViewModel(),
            };
        }

        base.OnFrameworkInitializationCompleted();
    }

    /// <summary>
    /// Occurs when an exception is thrown by an application but not handled.
    /// </summary>
    private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
    {
        // For more info see https://docs.microsoft.com/en-us/dotnet/api/system.windows.application.dispatcherunhandledexception?view=windowsdesktop-6.0

        Log.Error(e.Exception, "DispatcherUnhandledException");
    }
}
